package middle

import (
	"errors"
	"github.com/dgrijalva/jwt-go"
	"github.com/gin-gonic/gin"
	"log"
	"net/http"
)

type jwtToken struct{}

var JwtTOKEN jwtToken

//定义token中携带的信息
type CustClaims struct {
	Username string `json:"username"`
	Password string `json:"password"`
	jwt.StandardClaims
}

//加解密因子
const SECRET = "cmdbdevops"

//解析token
func (j *jwtToken) ParseToken(tokenString string) (claims *CustClaims, err error) {
	token, err := jwt.ParseWithClaims(tokenString, &CustClaims{}, func(token *jwt.Token) (interface{}, error) {
		return []byte(SECRET), nil
	})
	if err != nil {
		log.Printf("parse token failed", err)
		if ve, ok := err.(*jwt.ValidationError); ok {
			if ve.Errors&jwt.ValidationErrorMalformed != 0 {
				return nil, errors.New("TokenMalformed")
			} else if ve.Errors&jwt.ValidationErrorExpired != 0 {
				return nil, errors.New("TokenExpired")
			} else if ve.Errors&jwt.ValidationErrorNotValidYet != 0 {
				return nil, errors.New("TokenNotValidYet")
			} else {
				return nil, errors.New("TokenInvalid")
			}
		}
	}
	//转换成*CustClaims类型并返回
	if claims, ok := token.Claims.(*CustClaims); ok && token.Valid {
		return claims, nil
	}
	return nil, errors.New("解析token失败")
}

func JWTAuto() gin.HandlerFunc {
	return func(c *gin.Context) {
		//对接口进行放行
		if len(c.Request.URL.String()) >= 10 && c.Request.URL.String()[0:10] == "/api/login" {
			c.Next()
		} else {
			//处理验证逻辑
			token := c.Request.Header.Get("Authorization")
			if token == "" {
				c.JSON(http.StatusBadRequest, gin.H{
					"msg":  "请求未携带token，无权限访问",
					"data": nil,
				})
				c.Abort()
				return
			}
			//解析token内容
			claims, err := JwtTOKEN.ParseToken(token)
			if err != nil {
				//token过期错误
				if err.Error() == "TokenExpired"{
					c.JSON(http.StatusBadRequest, gin.H{
						"msg":  "授权已过期",
						"data": nil,
					})
					c.Abort()
					return
				}
				//其他解析错误
				c.JSON(http.StatusBadRequest, gin.H{
					"msg":  err.Error(),
					"data": nil,
				})
				c.Abort()
				return
			}
			c.Set("claims",claims)
			c.Next()
		}

	}
}





















